package com.qire.common.concurrent;

import com.qire.antscore.common.AntsThreadBuilder;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.function.TaskAction;

import java.util.concurrent.ThreadFactory;

/**
 * 运行线程包装器
 * @param <T> 处理数据类型
 */
public abstract class RunWrapper<T, R extends RunWrapper<T,R>> {

    /** 线程工厂 */
    private final ThreadFactory threadFactory;

    /** 调度器 */
    private Scheduler scheduler = Scheduler.Sync;

    /** 处理数据 */
    protected T data;

    /** 处理工人 */
    protected Worker<T> worker;

    /**
     * 线程程序包装器
     * @param threadName 线程名
     */
    public RunWrapper(String threadName) {
        this.threadFactory = AntsThreadBuilder.newAntsThreadFactory(threadName);
    }

    public R map(T data) {
        this.data = data;
        return (R) this;
    }

    /**
     * 指定调度基于的调度器
     * @param scheduler 调度器
     * @return RunWrapper<T>
     */
    public R schedulerBy(Scheduler scheduler) {
        this.scheduler = scheduler;
        return (R) this;
    }

    /**
     * 指定调度的处理程序，可追加多个程序
     * @param taskAction 处理程序
     * @return RunWrapper<T>
     */
    public R andThen(TaskAction<T> taskAction) {
        if(ObjectUtil.isNull(this.worker)) {
            this.worker = new Worker<T>(taskAction, scheduler);
        } else {
            this.worker = this.worker.andThen(new Worker<T>(taskAction, scheduler));
        }
        return (R) this;
    }

    /**
     * 开始调度
     * @return RunWrapper<T>
     */
    public final synchronized R accept() {
        if(ObjectUtil.nonNull(worker)) {
            threadFactory.newThread(buildWorker()).start();
        }
        return (R) this;
    }

    /**
     * @return 创建一个工人
     */
    protected abstract Runnable buildWorker();

}